using CfgTable;
using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System;

namespace IQIGame.Onigao.GamePlay
{
    public class UIN_HeroUpAwake : UIBaseNode
    {

        #region Template Generate,don't modify
        protected partial class UIB_UIN_HeroUpAwake
        {
            #region ObjectBinding Generate
            public IQIGame.Onigao.Framework.ExButton btnPrevious { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnNext { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnAwaken { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnBack { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textName { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textLvCurr { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textLvNext { protected set; get; }
            public UnityEngine.GameObject imageLvNext { protected set; get; }
            public UnityEngine.GameObject costMoney { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textCurrState { protected set; get; }
            public UnityEngine.GameObject skillRoot { protected set; get; }
            public UnityEngine.GameObject skinRoot { protected set; get; }
            public UnityEngine.GameObject costItems { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textUnlockSkin { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textUnlockSkill { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnPrevious", out var __tbv0);
                this.btnPrevious = __tbv0;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnNext", out var __tbv1);
                this.btnNext = __tbv1;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnAwaken", out var __tbv2);
                this.btnAwaken = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnBack", out var __tbv3);
                this.btnBack = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textName", out var __tbv4);
                this.textName = __tbv4;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textLvCurr", out var __tbv5);
                this.textLvCurr = __tbv5;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textLvNext", out var __tbv6);
                this.textLvNext = __tbv6;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("imageLvNext", out var __tbv7);
                this.imageLvNext = __tbv7;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("costMoney", out var __tbv8);
                this.costMoney = __tbv8;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textCurrState", out var __tbv9);
                this.textCurrState = __tbv9;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("skillRoot", out var __tbv10);
                this.skillRoot = __tbv10;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("skinRoot", out var __tbv11);
                this.skinRoot = __tbv11;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("costItems", out var __tbv12);
                this.costItems = __tbv12;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textUnlockSkin", out var __tbv13);
                this.textUnlockSkin = __tbv13;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textUnlockSkill", out var __tbv14);
                this.textUnlockSkill = __tbv14;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        #region fields & properties
        UIN_CostMoney costMoney = null;
        IrregularListAdapter<UIN_HeroUpItem> costItems = null;

        HeroData heroData;
        int lvInit = 0;
        int lvCurr = 0;
        int lvMax = 0;
        bool isMaxAwakenLv = false;
        int heroLv = 0;
        int maxHeroLv = 0;
        bool isMaxHeroLv = false;
        CfgHeroAwaken cfgHeroAwaken = null;
        CfgHeroAwaken nextCfgHeroAwaken = null;
        int cntCostItems = 0;

        protected UIB_UIN_HeroUpAwake ui { get; set; }
        #endregion

        protected override void BeforeInit()
        {
            ui = new UIB_UIN_HeroUpAwake();
            ui.InitBinding(this.csObjBind);
        }

        protected override void OnInit()
        {
            this.costMoney = this.InitChildNode<UIN_CostMoney>(this.ui.costMoney);
            this.costItems = this.InitIrregularList<UIN_HeroUpItem>(this.ui.costItems, this.OnCostItemChanged);

            this.ui.btnAwaken.onClick.AddListener(this.OnClickBtnAwaken);
            this.ui.btnBack.onClick.AddListener(this.OnClickBtnBack);
            this.ui.btnNext.onClick.AddListener(this.OnClickBtnNextLv);
            this.ui.btnPrevious.onClick.AddListener(this.OnClickBtnPreviousLv);
        }

        protected override void OnShow()
        {

        }

        protected override void OnHide()
        {
            this.heroData = null;
        }

        protected override void OnDispose()
        {
            this.heroData = null;
            this.costMoney = null;
            this.costItems = null;
        }

        public void Show(HeroData heroData)
        {
            this.SetData(heroData);
            this.Show();
            this.ViewShow();
        }

        #region 单击事件
        void OnClickBtnAwaken()
        {
            if (!this.costMoney.CheckIsEnough())
            {
                return;
            }

            this.SendUpAwakenLvAsync().Forget();
        }

        async UniTaskVoid SendUpAwakenLvAsync()
        {
            var result = await HeroModule.NetCore.CS_awaken(this.heroData.cid);
            if (result.IsSuccess)
            {
                HeroModule.Instance.UpHeroByPOD(result.heroPOD);

                UD_HeroUpLv udUP = UD_HeroUpLv.NewFromPool().SyncUpAwakenLevel(this.heroData, this.lvInit);
                this.OpenUI<UIHeroUpdatePop>(udUP);
                this.OnClickBtnBack();
            }
        }

        void OnClickBtnBack()
        {
            UIN_HeroUpdate parent = this.parentNode as UIN_HeroUpdate;
            if (parent == null)
                return;
            parent.ViewDefault();
        }

        void OnClickBtnPreviousLv()
        {
            int lvCurr = this.lvCurr == this.lvMax ? this.lvMax - 1 : this.lvCurr;
            int lv = Math.Max(0, lvCurr - 1);
            if (lv == lvCurr)
                return;
            this.SetCurrAwakenLv(lv);
            this.ViewCurr();
        }

        void OnClickBtnNextLv()
        {
            int lv = Math.Min(this.lvMax, this.lvCurr + 1);
            if (lv == this.lvCurr)
                return;
            this.SetCurrAwakenLv(lv);
            this.ViewCurr();
        }
        #endregion

        private void SetData(HeroData data)
        {
            this.heroData = data;
            this.OnSetData();
        }

        private void OnSetData()
        {
            this.lvInit = this.heroData.awakenLevel;
            this.lvMax = this.heroData.maxAwakenLv;
            this.isMaxAwakenLv = this.lvMax <= this.lvInit;

            this.heroLv = this.heroData.level;
            this.maxHeroLv = this.heroData.maxLv;
            this.isMaxHeroLv = this.maxHeroLv <= this.heroLv;
        }

        private void SetCurrAwakenLv(int awakenLv)
        {
            awakenLv = awakenLv == this.lvMax ? this.lvMax - 1 : awakenLv;

            this.lvCurr = awakenLv;
            this.cfgHeroAwaken = this.heroData.GetCfgHeroAwaken(awakenLv);
            this.nextCfgHeroAwaken = null;
            if (awakenLv >= 0 && awakenLv < this.lvMax)
            {
                this.nextCfgHeroAwaken = this.heroData.GetCfgHeroAwaken(awakenLv + 1);
            }
            this.cntCostItems = cfgHeroAwaken.Cost.Count / APIUIConst.CostDefaultSpacing;
        }

        private void ViewShow()
        {
            if (this.heroData == null)
                return;

            this.SetCurrAwakenLv(this.lvInit);
            this.ViewCurr();
        }

        private void ViewCurr()
        {
            bool isCurrLv = this.lvCurr == this.lvInit;
            bool isCanUp = isCurrLv && this.isMaxHeroLv && !this.isMaxAwakenLv;
            bool isFinish = (this.lvCurr < this.lvInit) || this.isMaxAwakenLv;
            bool isBackState = !isCanUp && (isFinish || this.lvCurr < this.lvMax);

            this.ui.btnNext.SetActive(!isCanUp && this.lvCurr < this.lvMax - 1);
            this.ui.btnPrevious.SetActive(!isCanUp && this.lvCurr > 0);

            int currHeroLv = cfgHeroAwaken.MaxHeroLevel;
            int nextHeroLv = nextCfgHeroAwaken?.MaxHeroLevel ?? 0;

            this.ui.textLvCurr.text = currHeroLv.ToString();
            this.ui.textLvNext.text = nextHeroLv.ToString();

            this.ShowCostMoney(isFinish);
            this.ShowCostItem(isFinish);

            this.ui.textCurrState.SetActive(isBackState);
            if (isBackState)
            {
                this.ui.textCurrState.text = APIUIHeroInfo.GetStrUpHeroAwakenCondition(currHeroLv, isFinish);
                //this.ui.textCurrState.indexSwitchColor = isFinish ? 1 : 0;
            }

            this.ui.btnAwaken.SetActive(isCanUp);
            this.ui.btnBack.SetActive(isBackState);

            this.ui.textName.text = APIUIHeroInfo.GetAwakenLevelTitle(this.lvCurr + 1);

            ShowUnlockSkill();
            ShowUnlockSkin();
        }

        private void ShowCostMoney(bool isFinish)
        {
            if (cfgHeroAwaken.GoldCost.Count < 2 || isFinish)
            {
                this.costMoney.Hide();
            }
            else
            {
                this.costMoney.Show(cfgHeroAwaken.GoldCost[0], cfgHeroAwaken.GoldCost[1]);
            }
        }

        private void ShowCostItem(bool isFinish)
        {

            this.costItems.RefillCells(4);
        }

        private void OnCostItemChanged(UIN_HeroUpItem item, int index)
        {
            int cid = 0, numCost = 0;
            if (index < this.cntCostItems)
            {
                var cfg = this.cfgHeroAwaken;
                int kStart = index * APIUIConst.CostDefaultSpacing;
                cid = cfg.Cost[kStart];
                numCost = cfg.Cost[kStart + 1];
            }
            item.Show(cid, numCost);
        }

        private void ShowUnlockSkill()
        {
            // TODO - 解锁技能
            int cid = cfgHeroAwaken.UnlockHomelandSkillID;
            bool isActive = false;//cid > 0;
            if (isActive)
            {
                // var cfgSkin = TableCenter.heroSkin.Get(cid);
                // this.ui.textUnlockSkill.text = APIUIHeroInfo.GetAwakenUnlockSkill(cfgSkin.Name);
            }
            this.ui.skillRoot.SetActive(isActive);
        }

        private void ShowUnlockSkin()
        {
            int cid = cfgHeroAwaken.UnlockHeroSkin;
            bool isActive = cid > 0;
            if (isActive)
            {
                var cfgSkin = TableCenter.heroSkin.Get(cid);
                this.ui.textUnlockSkin.text = APIUIHeroInfo.GetAwakenUnlockSkin(cfgSkin.Name);
            }
            this.ui.skinRoot.SetActive(isActive);
        }
    }
}
